#include "PriQueue.h"
#include <cstdlib>
#include <iostream>
/*
 * PriQueue.cpp
 *
 *  Created on: Sep 17, 2009
 *      Author: Cha
 */

using namespace std;

PriQueue::PriQueue(){
	root = NULL;
	iter = NULL;
}

void PriQueue::enqueue(Board *state, int priority){
	/* create a QueueElem from arguments */
	QueueElem *new_elem = (QueueElem *)malloc(sizeof(struct QueueElem));
	new_elem->saved_board = state;
	new_elem->h_of_n = priority;

	/* insert new_elem into the list */
	bool inserted = false;
	if(root == NULL){
		root = new_elem;
		root->next = NULL;
		root->prev = NULL;
		iter = root;
	}
	else{
		/*find where to insert new element */
		QueueElem *temp;
		iter = root;
		while(iter != NULL  && !inserted){
			if(new_elem->h_of_n <= iter->h_of_n){
				if(iter == root){
					new_elem->next = iter;
					iter->prev = new_elem;
					root = new_elem;
					iter = root;
				}
				else{
					new_elem->prev = iter->prev;
					new_elem->next = iter;
					(iter->prev)->next = new_elem;
					iter->prev = new_elem;
				}
				inserted = true;
			}
			temp = iter;
			iter = iter->next;
		}
		/*if new_elem wasnt added to the list, it means its priority is too
		 * high. It will get shoved on the end.
		 */
		if(!inserted){
			new_elem->prev = temp;
			temp->next = new_elem;
			new_elem->next = NULL;
		}
	}
}

Board * PriQueue::dequeue(){
	QueueElem *temp;
	temp = root;
	root = root->next;
	return temp->saved_board;
}

void PriQueue::displayQueue(){
	Board *temp;
	int **board;
	iter = root;
	while(iter != NULL){
		temp = iter->saved_board;
		board = temp->config;
		cout << "-----------" << endl;
		for(int y = 0; y < temp->dimensions; y++){
			for(int z = 0; z < temp->dimensions; z++)
				cout << board[y][z] << "\t";
			cout << "\n";
		}
		iter = iter->next;
	}
}

